home *** CD-ROM | disk | FTP | other *** search
-
- /*© copyright 1991-96 UserLand Software, Inc. All Rights Reserved.*/
-
-
- /*
- Drives Frontier's component "do-script" handler. You can send any valid Frontier
- script across this channel.
-
- This program starts by sending a script with a syntax error, to test the error
- reporting mechanism.
-
- This is a very bare bones program with one window and no menu bar. To quit
- just close the window.
-
- It's much faster than the Apple Event-based version!
- */
-
-
- #include <AppleEvents.h>
- #include <Components.h>
- #include <GestaltEqu.h>
- #include <OSA.h>
-
- #define stringlength(s) (s [0])
-
- WindowPtr mainwindow = nil; /*the menu sharing test window*/
-
- Str255 windowmessage; /*the message that's displayed in the main window*/
-
-
-
-
- static void initmacintosh (void) {
-
- /*
- the magic stuff that every Macintosh application needs to do
- before doing anything else.
- */
-
- register short i;
-
- MaxApplZone ();
-
- InitGraf (&qd.thePort);
-
- InitFonts ();
-
- FlushEvents (everyEvent, 0);
-
- InitWindows ();
-
- InitMenus ();
-
- TEInit ();
-
- InitDialogs (0L);
-
- InitCursor ();
-
- for (i = 0; i < 5; i++) { /*register with Multifinder*/
-
- EventRecord ev;
-
- EventAvail (everyEvent, &ev); /*see TN180 -- splash screen*/
- } /*for*/
-
- DrawMenuBar ();
- } /*initmacintosh*/
-
-
- static void copystring (Str255 source, Str255 dest) {
-
- /*
- create a copy of source in dest. copy the length byte and
- all the characters in the source string.
-
- assume the strings are pascal strings, with the length byte in
- the first character of the string.
- */
-
- register short i, len;
-
- len = (short) source [0];
-
- for (i = 0; i <= len; i++)
- dest [i] = source [i];
- } /*copystring*/
-
-
- static Boolean pushstring (Str255 bssource, Str255 bsdest) {
-
- register short lensource = bssource [0];
- register short lendest = bsdest [0];
- register char *psource, *pdest;
-
- if ((lensource + lendest) > 255)
- return (false);
-
- pdest = (char *) bsdest + (char) lendest + 1;
-
- psource = (char *) bssource + 1;
-
- bsdest [0] += (char) lensource;
-
- while (lensource--) *pdest++ = *psource++;
-
- return (true);
- } /*pushstring*/
-
-
- static Boolean pushlong (long num, Str255 bsdest) {
-
- Str255 bsint;
-
- NumToString (num, bsint);
-
- return (pushstring (bsint, bsdest));
- } /*pushlong*/
-
-
- static void ellipsize (Str255 s, short width) {
-
- /*
- if the string fits inside the given number of pixels, fine -- do nothing
- and return.
-
- if not, return a string that does fit, with ellipses representing the
- deleted characters. ellipses are generated by pressing option-semicolon.
- */
-
- register char len;
- register short newwidth;
-
- if ((newwidth = StringWidth (s)) <= width) /*nothing to do, the string fits*/
- return;
-
- len = s [0]; /* current length in characters*/
-
- width -= CharWidth ('…'); /* subtract width of ellipses*/
-
- do { /*until it fits (or we run out of characters)*/
-
- newwidth -= CharWidth (s [len]);
-
- --len;
- } while ((newwidth > width) && (len != 0));
-
- ++len; /*make room for the ellipses*/
-
- s [len] = '…';
-
- s [0] = (char) len;
- } /*ellipsize*/
-
-
- static void centerstring (Rect r, Str255 s) {
-
- /*
- draw the string in the current font, size and style, centered inside
- the indicated rectangle.
- */
-
- register short rh = r.bottom - r.top;
- register short rw = r.right - r.left;
- register short h, v;
- FontInfo fi;
-
- GetFontInfo (&fi);
-
- ellipsize (s, rw); /*make sure it fits inside the rectangle, width-wise*/
-
- h = r.left + ((rw - StringWidth (s)) / 2);
-
- v = r.top + ((rh - (fi.ascent + fi.descent)) / 2) + fi.ascent;
-
- MoveTo (h, v);
-
- ClipRect (&r);
-
- DrawString (s);
- } /*centerstring*/
-
-
- static void setfontsizestyle (short fontnum, short fontsize, short fontstyle) {
-
- TextFont (fontnum);
-
- TextSize (fontsize);
-
- TextFace (fontstyle);
- } /*setfontsizestyle*/
-
-
- static void updatemainwindow (void) {
-
- Rect r;
- Str255 s;
-
- r = (*mainwindow).portRect;
-
- EraseRect (&r);
-
- setfontsizestyle (helvetica, 12, 0);
-
- centerstring (r, windowmessage);
-
- NumToString (FreeMem () / 1024, s);
-
- MoveTo (r.left + 3, r.bottom - 3);
-
- setfontsizestyle (geneva, 9, 0);
-
- DrawString (s);
-
- DrawString ("\pK");
- } /*updatemainwindow*/
-
-
- static void setwindowmessage (Str255 script, Str255 result) {
-
- copystring (script, windowmessage);
-
- pushstring ("\p returns ", windowmessage);
-
- pushstring (result, windowmessage);
-
- pushstring ("\p", windowmessage);
-
- SetPort (mainwindow);
-
- updatemainwindow ();
- } /*setwindowmessage*/
-
-
- static Boolean initmainwindow (void) {
-
- register WindowPtr w;
-
- w = mainwindow = GetNewWindow (128, nil, (WindowPtr) -1);
-
- if (w == nil)
- return (false);
-
- ShowWindow (w);
-
- return (true);
- } /*initmainwindow*/
-
-
- static Boolean stringtotext (Str255 s, Handle *htext) {
-
- register long len;
- register Handle h;
-
- len = s [0];
-
- h = NewHandle (len);
-
- if (h == nil)
- return (false);
-
- BlockMove (&s [1], *h, len);
-
- *htext = h;
-
- return (true);
- } /*stringtotext*/
-
-
- static Boolean texttostring (Handle htext, Str255 s) {
-
- long len;
-
- len = GetHandleSize (htext);
-
- if (len > 255)
- len = 255;
-
- BlockMove (*htext, &s [1], len);
-
- s [0] = (char) len;
-
- return (true);
- } /*texttostring*/
-
-
- static Boolean FrontierDoScript (Str255 script, Str255 returns) {
-
- /*
- Executes a Do Script message, using Frontier's UserTalk component
- interface. The first parameter contains a short script to be run.
- The second parameter is the string that Frontier returned as the value
- generated by running the script.
-
- Returns true if we were able to send the message to Frontier, and Frontier
- was able to compile and run the script and return a value. FrontierDoScript
- returns false if Frontier isn't running, or if the script didn't compile or
- if there was a communications error.
-
- Frontier is not limited to running 255-character scripts or returning
- 255-character returned values. This routine can easily be enhanced to handle
- larger scripts and returned values.
-
- Note that this sample code tests for the Component Manager and connects to
- the script server each time a script is executed. In production code, better
- performance can be obtained by keeping the component instance open until
- you're done with it.
- */
-
- register OSErr ec;
- ComponentInstance scriptcomp;
- AEDesc scriptdesc;
- AEDesc resultdesc = {typeNull, nil};
- long result;
-
- ec = Gestalt (gestaltComponentMgr, &result);
-
- if ((ec != noErr) || (result == 0)) {
-
- copystring ("\pThe Component Manager isn’t present. This application requires System 7.1 or QuickTime.", returns);
-
- return (false);
- }
-
- ec = AECreateDesc (typeChar, (Ptr) &script [1], stringlength (script), &scriptdesc);
-
- if (ec != noErr)
- return (false);
-
- scriptcomp = OpenDefaultComponent (kOSAComponentType, 'LAND');
-
- if (scriptcomp == nil) { /*couldn't connect to component*/
-
- AEDisposeDesc (&scriptdesc);
-
- copystring ("\pCouldn’t open the UserTalk scripting component.", returns);
-
- return (false);
- }
-
- ec = OSADoScript (scriptcomp, &scriptdesc, kOSANullScript, typeChar, kOSANullMode, &resultdesc);
-
- AEDisposeDesc (&scriptdesc);
-
- switch (ec) {
-
- case noErr: /*script ran without error*/
-
- texttostring (resultdesc.dataHandle, returns);
-
- break;
-
- case errOSAScriptError: /*error during script execution*/
-
- if (OSAScriptError (scriptcomp, kOSAErrorMessage, typeChar, &resultdesc) == noErr)
- texttostring (resultdesc.dataHandle, returns);
- else
- copystring ("\pThe script generated an error, but no message was provided.", returns);
-
- break;
-
- default: /*error trying to run the script*/
-
- copystring ("\pComponent Manager error. Its code number is ", returns);
-
- pushlong (ec, returns);
-
- pushstring ("\p.", returns);
-
- break;
- }
-
- AEDisposeDesc (&resultdesc);
-
- CloseComponent (scriptcomp);
-
- return (ec == noErr);
- } /*FrontierDoScript*/
-
-
- static void handledrag (EventRecord ev, WindowPtr w) {
-
- Rect r;
-
- r = qd.screenBits.bounds;
-
- r.top = r.top + GetMBarHeight ();
-
- r.left = r.left + 4;
-
- r.right = r.right - 4;
-
- r.bottom = r.bottom - 4;
-
- DragWindow (w, ev.where, &r);
- } /*handledrag*/
-
-
- static Boolean exitprogram (void) {
-
- /*
- returns true if the user clicks in the go-away box.
- */
-
- EventRecord ev;
- WindowPtr w;
-
- if (!WaitNextEvent (everyEvent, &ev, 1, nil))
- return (false);
-
- if (ev.what != mouseDown)
- return (false);
-
- switch (FindWindow (ev.where, &w)) {
-
- case inGoAway: /*click in go-away box to exit program*/
- return (TrackGoAway (w, ev.where));
-
- case inSysWindow:
- SystemClick (&ev, w);
-
- return (false);
-
- case inDrag:
- handledrag (ev, w);
-
- return (false);
-
- } /*switch*/
-
- return (false); /*don't exit the program*/
- } /*exitprogram*/
-
-
- static void waitseconds (long n) {
-
- register long endticks;
-
- endticks = TickCount () + (n * 60);
-
- while (TickCount () < endticks)
- SystemTask ();
- } /*waitseconds*/
-
-
- void main (void) {
-
- Str255 script, result;
- Boolean error;
- register short i;
-
- initmacintosh ();
-
- initmainwindow ();
-
- copystring ("\p94 + ", script);
-
- if (FrontierDoScript (script, result))
- copystring ("\pFrontierDoScript should have returned false.", result);
-
- setwindowmessage (script, result); /*should say "Can't compile this script..."*/
-
- waitseconds (1); /*give user a chance to see error message*/
-
- for (i = 1; i <= 50; ++i) {
-
- if (exitprogram ()) /*returns true if user clicks in go away box*/
- return;
-
- copystring ("\pstates.nthState (", script);
-
- pushlong (i, script);
-
- pushstring ("\p)", script);
-
- error = !FrontierDoScript (script, result);
-
- setwindowmessage (script, result);
-
- if (error)
- break;
- } /*while*/
-
- waitseconds (2); /*give user a chance to see the final result*/
- } /*main*/
-
-
-